// © 2020 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package org.unicode.icu.tool.cldrtoicu.ant;

import com.google.common.collect.ImmutableList;
import com.google.common.truth.BooleanSubject;
import com.google.common.truth.Truth;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Arrays;

@RunWith(JUnit4.class)
public class CleanOutputDirectoryTaskTest {
    // Not using the original field since we want this test to fail if this changes unexpectedly.
    private static final String WAS_GENERATED_LABEL =
        "Generated using tools/cldr/cldr-to-icu/build-icu-data.xml";

    // Commented version of the label for test data.
    private static final String WAS_GENERATED_LINE = "// " + WAS_GENERATED_LABEL;

    private final static ImmutableList<String> HEADER = ImmutableList.of(
        "Header#1",
        "Header#2",
        WAS_GENERATED_LABEL);

    @Test
    public void testWasFileAutoGenerated_lenientMatching() throws IOException {
        // Testing comment prefixes (// or # supported equally)
        assertWasAutogenerated("// Header#1", "// Header#2").isTrue();
        assertWasAutogenerated("# Header#1", "# Header#2").isTrue();
        assertWasAutogenerated("# Header#1", "// Header#2").isTrue();
        assertWasAutogenerated("//    Header#1", "//Header#2").isTrue();
        // Extra lines
        assertWasAutogenerated("// Header#1", "// Header#2", "// More comment", "Not a comment").isTrue();
        // BOM is ignored on first line
        assertWasAutogenerated("\uFEFF// Header#1", "// Header#2").isTrue();
    }

    @Test
    public void testWasFileAutoGenerated_lenientMatching_fail() throws IOException {
        // New blank line.
        assertWasAutogenerated("", "// Header#1", "// Header#2").isFalse();
        // Duplicated line.
        assertWasAutogenerated("// Header#1", "// Header#1").isFalse();
        // Reversed lines.
        assertWasAutogenerated("// Header#2", "// Header#1").isFalse();
        // Not commented.
        assertWasAutogenerated("Header#1", "Header#2").isFalse();
        // Extra blank line.
        assertWasAutogenerated("// Header#1", "", "// Header#2").isFalse();
        // Misplaced BOM.
        assertWasAutogenerated("// Header#1", "\uFEFF// Header#2").isFalse();
    }

    @Test
    public void testWasFileAutoGenerated_withLabel() throws IOException {
        // With the label in the header comment section everything passes.
        assertWasAutogenerated("// Header#1", "// Header#2", WAS_GENERATED_LINE).isTrue();
        assertWasAutogenerated("// Hello", "// World", WAS_GENERATED_LINE).isTrue();
        assertWasAutogenerated("// Shorter Header", WAS_GENERATED_LINE).isTrue();
        assertWasAutogenerated("// This", "// Is", "// A", "// Longer", "// Header", WAS_GENERATED_LINE).isTrue();
        assertWasAutogenerated("// Where the label is", WAS_GENERATED_LINE, "// Does not matter").isTrue();
        assertWasAutogenerated(WAS_GENERATED_LINE).isTrue();
    }

    @Test
    public void testWasFileAutoGenerated_matchingEndsAfterComments() throws IOException {
        assertWasAutogenerated("// Header#1", "// Header#Changed", WAS_GENERATED_LINE).isTrue();
        // Label outside the header comment section does not count.
        assertWasAutogenerated("// Header#1", "// Header#Changed", "Not a comment", WAS_GENERATED_LINE).isFalse();
    }

    private static BooleanSubject assertWasAutogenerated(String... fileLines) throws IOException {
        return Truth.assertWithMessage("wasAutogenerated: %s", Arrays.asList(fileLines))
            .that(CleanOutputDirectoryTask.wasFileAutoGenerated(testFile(fileLines), HEADER));
    }

    private static BufferedReader testFile(String... lines) {
        return new BufferedReader(new StringReader(String.join("\n", lines) + "\n"));
    }
}
